home *** CD-ROM | disk | FTP | other *** search
- /* File "bsdsocks.cpp", Light Sockets - Copyright (C) Matt Slot, 1996 */
- /* BSD/UNIX sockets implementation for "Light Sockets" abstraction library. */
-
- #include <errno.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <time.h>
- #include <unistd.h>
-
-
- #include "stddebug.h"
- #include "stdtypes.h"
-
- #include "bsdsocks.h"
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* Global/Static Data */
-
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- BSDSocketStack::BSDSocketStack(SocketRef socket) : NetworkStack(socket) {
- theSocket = 0;
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- BSDSocketStack::~BSDSocketStack() {
- DoDispose();
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult BSDSocketStack::DoLoad() {
- SocketResult error = eSocketNoError;
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoLoad(), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoUnload() {
- SocketResult error = eSocketNoError;
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoUnload(), 0);
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult BSDSocketStack::DoCreate() {
- SocketResult error = eSocketNoError;
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoCreate(), 0);
-
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- theSocket = ::socket(AF_INET, SOCK_DGRAM, 17);
- qThrowIfTrue(theSocket < 0, errno, "Error creating socket");
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- // else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
-
-
- /* CATCH */
- qCatch();
-
- if (error) {
- theSocket = 0;
- DoDispose();
- }
-
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoTickle() {
- SocketResult error = eSocketNoError;
- fd_set read_fdset;
- struct timeval timeout;
-
- /* Parameter validation */
- qThrowIfNull(theSocket, eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoTickle(), 0);
-
- /* Check for any incoming connection requests */
- FD_ZERO(&read_fdset);
- FD_SET(theSocket, &read_fdset);
- timeout.tv_sec = 0; timeout.tv_usec = 0;
- while(select(getdtablesize(), &read_fdset, 0, 0, &timeout) > 0) {
-
- if (FD_ISSET(theSocket, &read_fdset)) {
- SocketAddress remoteAddr;
- Int addrLen = sizeof(remoteAddr.buffer.tcpip);
- Char8 buff[PING_BUFFER_SIZE];
- SInt32 buffLen = sizeof(buff);
-
- buffLen = recvfrom(theSocket, buff, buffLen, 0,
- &remoteAddr.buffer.tcpip, &addrLen);
- if (buffLen < 0) qTraceIfError(buffLen, "Error reading packet")
-
- remoteAddr.type = eSocketTypeUDP;
- remoteAddr.length = sizeof(remoteAddr.buffer.tcpip);
- qTraceIfError(DatagramRead(buff, buffLen, &remoteAddr), 0);
- }
-
- /* Try again */
- FD_ZERO(&read_fdset);
- FD_SET(theSocket, &read_fdset);
- timeout.tv_sec = 0; timeout.tv_usec = 0;
- }
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoDispose() {
- SocketResult error = eSocketNoError;
-
- if (theSocket) {
- if (qIsSocketTypeUDP(socket->GetSocketType())) {
- close(theSocket);
- theSocket = 0;
- }
- else if (qIsSocketTypeRawIP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else if (qIsSocketTypeTCP(socket->GetSocketType())) {
- qThrowErr(eSocketErrNoSupport, kSocketErrNoSupportStr);
- }
- else qThrowErr(eSocketErrBadParam, kSocketErrBadParamStr);
- }
-
- /* Implement socket callback chain */
- qTraceIfError(NetworkStack::DoDispose(), 0);
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult BSDSocketStack::DoBind(SocketAddressPtr reqAddress,
- SocketAddressPtr retAddress) {
- SocketResult error = eSocketNoError;
- SocketAddress localAddr;
- UInt16 savePort = 0;
-
- /* Parameter validation */
- qThrowIfNull(theSocket, eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoBind(reqAddress, retAddress), 0);
-
- if (reqAddress) {
- qThrowIfTrue(bind(theSocket, &reqAddress->buffer.tcpip,
- sizeof(reqAddress->buffer.tcpip))< 0, errno,"Error binding socket");
- }
- else {
- localAddr.buffer.tcpip.type = AF_INET;
- localAddr.buffer.tcpip.port = 0;
- localAddr.buffer.tcpip.host = 0;
- memset(localAddr.buffer.tcpip.data, 0,
- sizeof(localAddr.buffer.tcpip.data));
-
- qThrowIfTrue(bind(theSocket, &localAddr.buffer.tcpip,
- sizeof(localAddr.buffer.tcpip))<0,errno,"Error binding socket");
- }
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoUnbind(void) {
- SocketResult error = eSocketNoError;
-
- /* Parameter validation */
- qThrowIfNull(theSocket, eSocketErrBadParam, kSocketErrBadParamStr);
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoUnbind(), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoAddressResolve(Char8 *textAddress,
- SocketAddressPtr socketAddress) {
- SocketResult error = eSocketNoError;
- struct hostent *hostInfo;
- UInt32 host=0;
-
- /* Parameter validation */
- qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
- qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
-
- if (hostInfo = gethostbyname(textAddress))
- host = ** (UInt32 **) hostInfo->h_addr_list;
- else if ((*textAddress >= '0') && (*textAddress <= '9')) {
- UInt8 ipBytes[4];
- UInt32 i;
- Char8 *token, *dummy;
- Char8 dottedBuff[ARBITRARY_BUFFER_SIZE];
-
- strcpy(dottedBuff, textAddress);
- for(i=0, token = strtok(dottedBuff, "."); (i<4) && token;
- i++, token = strtok((Char8 *) NULL, "."))
- ipBytes[i] = strtol(token, &dummy, 10);
-
- if (i==4)
- memcpy(&host, ipBytes, sizeof(host));
- else
- qThrowErr(eSocketErrUnknown, kSocketErrUnknownStr);
- }
-
- socketAddress->type = eSocketTypeUDP; /* For a guess */
- socketAddress->length = sizeof(socketAddress->buffer.tcpip);
- socketAddress->buffer.tcpip.type = AF_INET;
- socketAddress->buffer.tcpip.port = 0;
- socketAddress->buffer.tcpip.host = host;
- memset(socketAddress->buffer.tcpip.data, 0,
- sizeof(socketAddress->buffer.tcpip.data));
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoAddressLookup(SocketAddressPtr socketAddress,
- Char8 *textAddress) {
- SocketResult error = eSocketNoError;
- struct hostent *host_info;
-
- /* Parameter validation */
- qAssertIfNull(socketAddress, eSocketErrBadParam, kSocketErrBadParamStr);
- qAssertIfNull(textAddress, eSocketErrBadParam, kSocketErrBadParamStr);
-
- if (host_info = gethostbyaddr((Char8 *) &socketAddress->buffer.tcpip.host,
- sizeof(socketAddress->buffer.tcpip.host), AF_INET))
- strcpy(textAddress, host_info->h_name);
- else {
- UInt8 ipBytes[4];
-
- memcpy(ipBytes, &socketAddress->buffer.tcpip.host, sizeof(ipBytes));
- sprintf(textAddress, "%u.%u.%u.%u",
- (UInt) ipBytes[0], (UInt) ipBytes[1],
- (UInt) ipBytes[2], (UInt) ipBytes[3]);
- }
-
- /* CATCH */
- qCatch();
-
- if (error && textAddress) *textAddress = 0;
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult BSDSocketStack::DoDatagramWrite(Byte8 *dataPtr, UInt32 dataLen,
- SocketAddressPtr address) {
- SocketResult error = eSocketNoError;
- SInt32 result;
-
- /* Parameter validation */
- qThrowIfNull(theSocket, eSocketErrBadParam, kSocketErrBadParamStr);
-
- result = sendto(theSocket, dataPtr, dataLen, 0, &address->buffer.tcpip,
- sizeof(address->buffer.tcpip));
- qThrowIfTrue(result < 0, errno, "Error writing packet");
-
- /* Implement socket callback chain */
- qThrowIfError(NetworkStack::DoDatagramWrite(dataPtr, dataLen, address), 0);
-
-
- /* CATCH */
- qCatch();
- return(error);
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- #pragma mark -
-
- SocketResult BSDSocketStack::DoStreamServer(UInt32 sessions) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoStreamClient(SocketAddressPtr address) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoStreamWrite(Byte8 *dataPtr, UInt32 dataLen) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
- /* **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** */
-
- SocketResult BSDSocketStack::DoStreamClose(Bool8 orderly) {
- return(eSocketErrNoSupport); /* Function not supported yet */
- }
-
-